<template>
    <div v-if="enable">
     <el-radio-group v-model="conditionType" size="small" style="padding-left:20px">
      <el-radio value="1">表单字段</el-radio>
      <el-radio value="2">流程表达式</el-radio>
    </el-radio-group>
    <el-divider></el-divider>
    <el-form v-if="conditionType === '2'"  ref="form" class="act-form" label-width="100px">
      <el-form-item :label="label">
        <el-input placeholder="请输入流程表达式" v-model="condition" class="input-with-select">
          <template #append>
            <el-button  @click="showSelectConditionDialog" icon="search"></el-button>
          </template>
        </el-input>
      </el-form-item>
    </el-form>
    <ConditionalDialog ref="conditionDialog" @setCondition="setCondition"></ConditionalDialog>


     <div v-if="conditionType === '1'" style="padding:5px">
        <el-button type="primary" style="margin-bottom:5px;"  size="small" @click="addCondition">添加</el-button>
    <!-- <el-button type="primary" style="margin:5px"  size="small" @click="openAddButton">添加按钮</el-button> -->
        <el-table
          :data="tableData"
           border
           size="small"
          >
          <el-table-column
            prop="field"
            label="字段"
            width="120">
            <template #default="scope">
              <el-select  v-model="scope.row.field" placeholder="请选择">
                  <el-option
                    v-for="(item, index) in fieldOption"
                    :key="index"
                    :label="item.name"
                    :value="item.id">
                  </el-option>
                </el-select>
            </template>
          </el-table-column>
          <el-table-column
            prop="compare"
            label="条件"

            width="120">
             <template #default="scope">
              <el-select  v-model="scope.row.compare" placeholder="请选择">
                <el-option value="<" label="小于"></el-option>
                <el-option value=">" label="大于"></el-option>
                <el-option value="<=" label="小于等于"></el-option>
                <el-option value="==" label="等于"></el-option>
                <el-option value=">=" label="大于等于"></el-option>
              </el-select>
            </template>
          </el-table-column>
          <el-table-column
            prop="value"
            label="值">
            <template #default="scope">
              <el-input  v-model="scope.row.value" placeholder="请输入内容"></el-input>
            </template>
          </el-table-column>
          <el-table-column
            prop="logic"
            label="逻辑"
            width="80">
              <template #default="scope">
                <el-select  v-model="scope.row.logic" placeholder="请选择">
                  <el-option
                      v-for="(item, index) in [{label:'且', value: 'and'},{label:'或', value: 'or'}]"
                      :key="index"
                      :label="item.label"
                      :value="item.value">
                    </el-option>
                </el-select>
            </template>
          </el-table-column>
          <el-table-column
            fixed="right"
            header-align="center"
            align="center"
            width="70"
            label="操作">
            <template #default="scope">
              <el-button type="danger" size="small"  text  @click="del(scope.row)">删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
     </div>
    </div>
</template>
<script>
   import cmdHelper from 'jp-bpmn-js-properties-panel/lib/helper/CmdHelper'
   import elementHelper from 'jp-bpmn-js-properties-panel/lib/helper/ElementHelper'
   import eventDefinitionHelper from 'jp-bpmn-js-properties-panel/lib/helper/EventDefinitionHelper'
   import { isAny } from 'jeeplus-bpmn/lib/features/modeling/util/ModelingUtil'
   import { is } from 'jeeplus-bpmn/lib/util/ModelUtil'
   import { getBusinessObject } from 'jeeplus-bpmn/lib/util/ModelUtil'
   import ConditionalDialog from './ConditionalDialog.vue'
   import pick from 'lodash.pick'
   import nodeSettingService from '@/api/flowable/nodeSettingService'
   export default {
     props: {
       element: {
         type: Object,
         default: undefined
       },
       bpmnModeler: {
         type: Object,
         default: undefined
       }
     },
     components: {
       ConditionalDialog
     },
     data () {
       return {
         label: '流程表达式',
         condition: '',
         conditionType: '1',
         visible: false,
         fieldOption: [],
         tableData: []
       }
     },
     computed: {
       enable () {
         if (this.element && getBusinessObject(this.element)) {
           let conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(this.element)
           if (!(is(this.element, 'bpmn:SequenceFlow') && this.isConditionalSource(this.element.source)) && !conditionalEventDefinition) {
             return false
           } else {
             return true
           }
         } else {
           return false
         }
       }
     },
     methods: {
       showSelectConditionDialog () {
         this.$refs.conditionDialog.show()
       },
       setCondition (val) {
         this.condition = val
       },
       isConditionalSource (element) {
         let CONDITIONAL_SOURCES = [
           'bpmn:Activity',
           'bpmn:StartEvent',
           'bpmn:ExclusiveGateway',
           'bpmn:InclusiveGateway',
           'bpmn:ComplexGateway'
         ]

         return isAny(element, CONDITIONAL_SOURCES)
       },
       addCondition () {
         this.tableData.push({field: '', compare: '<', value: '', logic: 'and', sort: 1})
       },
        del (row) {
          this.tableData.forEach((item, index) => {
            if (item === row) {
              this.tableData.splice(index, 1)
            }
          })
        },
        getExtensionElements (element) {
          let bo = getBusinessObject(element)
          return bo.extensionElements
        },
        createExtensionElements: function (element, bo) {
          var extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, this.bpmnModeler.get('bpmnFactory'))
          bo.extensionElements = extensionElements
          return extensionElements
        },
        isExtensionElements (element) {
          return is(element, 'bpmn:ExtensionElements')
        },
        getButtonsElement (element) {
          if (!this.isExtensionElements(element)) {
            return element.buttons
          } else {
            return this.getButtonsElementInsideExtensionElements(element)
          }
        },
        getButtonsElementInsideExtensionElements (extensionElements) {
          return find(extensionElements.values, function (elem) {
            return is(elem, 'flowable:Condition')
          })
        },
       updateElements (tableDatas) {
          let andConditionArra = []
          let orConditionArra = []
          tableDatas.forEach((val, index)=>{
            val.sort = index
            if(val.logic === 'and') {
              andConditionArra.push(val)
            }else{
              orConditionArra.push(val)
            }
          })
          let andConditionValue = andConditionArra.map((condition)=>{
            return `${condition.field}${condition.compare}${condition.value}`
          }).join('||')
          let orConditionValue = orConditionArra.map((condition)=>{
            return `${condition.field}${condition.compare}${condition.value}`
          }).join('&&')
          let conditionValue = ''
          if(andConditionValue === ''){
            conditionValue = orConditionValue
          } else if(orConditionValue === ''){
            conditionValue = andConditionValue
          }else{
            conditionValue = `(${orConditionValue})&&${andConditionValue}`
          }
          if(conditionValue !== ''){
            conditionValue = '${'+conditionValue+'}'
          }
          this.condition = conditionValue
          let element = this.element
          let bo = getBusinessObject(element)
          let parent = this.getExtensionElements(element)

          if (!parent && typeof this.createExtensionElements === 'function') {
            parent = this.createExtensionElements(element, bo)
          }
          let objList = []
          tableDatas.forEach((row) => {
            var condition = elementHelper.createElement('flowable:Condition', row, parent, this.bpmnModeler.get('bpmnFactory'))
            objList.push(condition)
          })

          let old = []
          if (this.element.businessObject.extensionElements) {
            this.element.businessObject.extensionElements.values.forEach((value) => {
              if (is(value, 'flowable:Condition')) {
                old.push(value)
              }
            })
          }
          this.bpmnModeler.get('commandStack').execute('properties-panel.update-businessobject-list', {
            element: element,
            currentObject: parent,
            propertyName: 'values',
            objectsToRemove: old
          })
          this.bpmnModeler.get('commandStack').execute('properties-panel.update-businessobject-list', {
            element: element,
            currentObject: parent,
            propertyName: 'values',
            objectsToAdd: objList
          })
        },
        updateProperty (conditionValue) {
          if (this.element) {
             let values = {condition: conditionValue,
               conditionType: 'expression'}
             var conditionType = values.conditionType
             var commands = []
             var bo = getBusinessObject(this.element)
             var conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(this.element)
             if (!bo) {
               return
             }
             var conditionProps = {
               body: undefined
             }
             var condition = values.condition
             conditionProps.body = condition
             var conditionOrConditionExpression
             if (conditionType) {
               conditionOrConditionExpression = elementHelper.createElement(
                'bpmn:FormalExpression',
                conditionProps,
                conditionalEventDefinition || bo,
                this.bpmnModeler.get('bpmnFactory')
              )

               var source = this.element.source

        // if default-flow, remove default-property from source
               if (source && source.businessObject.default === bo) {
                 commands.push(cmdHelper.updateProperties(source, { 'default': undefined }))
               }
             }

             var update = conditionalEventDefinition
        ? { condition: conditionOrConditionExpression }
        : { conditionExpression: conditionOrConditionExpression }
             this.bpmnModeler.get('modeling').updateProperties(this.element, update)
            //  commands.push(cmdHelper.updateBusinessObject(this.element, conditionalEventDefinition || bo, update))
           }
        }
     },
     watch: {
        tableData: {
          handler (newVal) {
            if (this.element && this.conditionType === '1') {
              this.updateElements(newVal)
            }
          },
          deep: true,
          immediate: false
        },
       condition: {
         handler (newVal) {
           this.updateProperty(newVal)
         },
         deep: false
       },
       conditionType (val) {
         this.bpmnModeler.get('modeling').updateProperties(this.element, { 'flowable:conditionType': val })
         if(this.conditionType === '1'){
           this.updateElements(this.tableData)
         }
       },
       'element': {
        async handler (newVal) {
           if (this.element) {
             let conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(this.element)
             let bo = getBusinessObject(this.element)
             let conditionExpression = conditionalEventDefinition? conditionalEventDefinition.condition: bo.conditionExpression
             let root = this.bpmnModeler.get('canvas').getRootElement().businessObject
             let startEvents = root.flowElements.filter((flowElement) => {
                return is(flowElement, 'bpmn:StartEvent')
              })
              
             if(!(bo.$attrs && bo.$attrs['flowable:conditionType'])){
                  // 读取条件类型
                  let data = await nodeSettingService.queryValueByKey({
                    processDefId: root.id,
                    taskDefId: this.element.id,
                    key: 'conditionType'
                  })
                  this.conditionType = '' + data
              }else{
                this.conditionType = bo.$attrs['flowable:conditionType']
              }
              if (conditionExpression) {
                this.condition = conditionExpression.get('body')
              } else {
                this.condition = ''
              }
              this.fieldOption = []
              if(startEvents.length > 0){
                  let startEvent = startEvents[0]
                  if (startEvent.extensionElements) {
                        startEvent.extensionElements.values.forEach((value) => {
                          if (is(value, 'flowable:FormProperty')) {
                            value = pick(value, 'id', 'name')
                            value.readable = (value.readable === undefined ? true : value.readable)
                            value.writable = (value.writable === undefined ? true : value.writable)
                            this.fieldOption.push(JSON.parse(JSON.stringify(value)))
                          }
                      })
                    }
                  this.tableData = []
                  if (this.element.businessObject.extensionElements) {
                    this.element.businessObject.extensionElements.values.forEach((value) => {
                      if (is(value, 'flowable:Condition')) {
                        value = pick(value, 'field', 'compare', 'value', 'logic', 'sort')
                        this.tableData.push(JSON.parse(JSON.stringify(value)))
                      }
                    })
                  }
              }

           }
         },
         immediate: true,
         deep: true
       }
     }
   }
</script>
